﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Movies.Web.Models;
using Movies.Web.Models.ViewModel;

namespace Movies.Web.Controllers
{
    public class MoviesController : Controller
    {
        public readonly MoviesDb _moviesDb = null;

        public MoviesController()
        {
            _moviesDb = new MoviesDb();
        }
        

        //
        // GET: /Movies/
        public ActionResult Index(int? releaseYear)
        {
            IList<Movie> model = new List<Movie>();

            if (releaseYear.HasValue)
                model = _moviesDb.Movies.Where(x => x.RelaseDate.Value.Year == releaseYear).ToList();
            else
                model = _moviesDb.Movies.ToList();

            return View(model);
        }

        //
        // GET: /Movies/Details/5

        public ActionResult Details(int id)
        {
            var movie = _moviesDb.Movies.Where(x => x.Id == id).SingleOrDefault();

            if (movie == null)
            {
                TempData.Add("errorMessage", "The Id was not found, please choose from the following list");
                return RedirectToAction("index");
            }

            return View(movie);
        }

        //
        // GET: /Movies/Create

        public ActionResult Create()
        {
            ViewBag.ActorChoices = _moviesDb.Actors.ToDictionary(x => x.Id, y => y.FullName);
            ViewBag.DirectorChoices = _moviesDb.Directors.ToDictionary(x => x.Id, y => y.FullName);
            return View();
        } 

        //
        // POST: /Movies/Create

        [HttpPost]
        public ActionResult Create(MovieViewModel movie)
        {
            IList<Actor> actors = new List<Actor>();
            var director = _moviesDb.Directors.Where(x => x.Id == movie.SelectedDirector).SingleOrDefault();

            if (!ModelState.IsValid || director == null)
            {
                ViewBag.DirectorChoices = _moviesDb.Directors.ToDictionary(x => x.Id, y => y.FullName);
                ViewBag.ActorChoices = _moviesDb.Actors.ToDictionary(x => x.Id, y => y.FullName);
                return View();
            }

            try
            {
                    // TODO: Add insert logic here
                foreach (var actorId in movie.ActorIds)
                {
                    var actor = _moviesDb.Actors.Where(x => x.Id == actorId).SingleOrDefault();

                    if (actor != null)
                    {
                        actors.Add(actor);
                    }
                    
                }
                


                _moviesDb.Movies.Add(movie.MapToMovie(actors, director));
                _moviesDb.SaveChanges();
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                TempData.Add("errorMessage", ex.Message);
                return View();
            }
        }
        
        //
        // GET: /Movies/Edit/5
 
        public ActionResult Edit(int id)
        {
            var movie = _moviesDb.Movies.Where(x => x.Id == id).SingleOrDefault();
            MovieViewModel model = new MovieViewModel();

            if (!HasValidMovie(movie))
            {
                return RedirectToAction("index");
            }

            ViewBag.ActorChoices = _moviesDb.Actors.ToDictionary(x => x.Id, y => y.FullName);
            ViewBag.DirectorChoices = _moviesDb.Directors.ToDictionary(x => x.Id, y => y.FullName);
            return View(model.MapToModel(movie));
        }

        //
        // POST: /Movies/Edit/5
        [HttpPost]
        public ActionResult Edit(int id, MovieViewModel movieToUpdate)
        {
            var director = _moviesDb.Directors.Where(x=> x.Id == movieToUpdate.SelectedDirector).SingleOrDefault();

            if (!ModelState.IsValid || director== null )
            {
                ViewBag.ActorChoices = _moviesDb.Actors.ToDictionary(x => x.Id, y => y.FullName);
                ViewBag.DirectorChoices = _moviesDb.Directors.ToDictionary(x => x.Id, y => y.FullName);
                return View();
            }

            try
            {
                var movie = _moviesDb.Movies.Where(x => x.Id==id).SingleOrDefault();

                if (!HasValidMovie(movie))
                {
                    return RedirectToAction("index");
                }

                
                    // remap
                    movie.Name = movieToUpdate.MovieName;
                    movie.Rating = movieToUpdate.Rating;
                    movie.RelaseDate = movieToUpdate.ReleaseDate;
                    movie.DirectedBy = director;
                    movie.DirectedBy.MoviesDirected.Add(movie);
                    movie.Actors.Clear();

                    // rebuild
                    foreach (var actorId in movieToUpdate.ActorIds)
                    {
                        var actor = _moviesDb.Actors.Where(x => x.Id == actorId).SingleOrDefault();

                        if (actor != null)
                        {
                            actor.MoviesStaredIn.Add(movie);
                            movie.Actors.Add(actor);
                        }
                    }

                    _moviesDb.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /Movies/Delete/5
        public ActionResult Delete(int id)
        {
            var movie = _moviesDb.Movies.Where(x => x.Id == id).SingleOrDefault();

            if (!HasValidMovie(movie))
            {
                return RedirectToAction("index");
            }


            return View(movie);
        }

        private bool HasValidMovie(Movie movie)
        {
            bool isValid = false;

            if (movie == null)
            {
                TempData.Add("errorMessage", "The Id was not found, please choose from the following list");
            }
            else
            {
                isValid = true;
            }

            return isValid;
        }

        //
        // POST: /Movies/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, Movie movieToDelete)
        {
            try
            {
                // TODO: Add delete logic here
                var movie = _moviesDb.Movies.Where(x => x.Id == id).SingleOrDefault();

                if (!HasValidMovie(movie))
                {
                    return RedirectToAction("index");
                }

                _moviesDb.Movies.Remove(movie);
                _moviesDb.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
}
